package one.stand.interceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import one.stand.aop.ApiController;
import one.stand.entity.TokenEntity;
import one.stand.enums.ResultEnum;
import one.stand.exception.*;
import one.stand.feign.CrmFegin;
import one.stand.feign.LoginFegin;
import one.stand.model.ResultModel;
import one.stand.request.BusinessCardRequest;
import one.stand.request.TokenRequest;
import one.stand.util.IpUtil;
import one.stand.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Administrator
 */
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
    protected static final Logger log = LoggerFactory.getLogger(LoginInterceptor.class);

    @Autowired
    @Lazy
    private CrmFegin crmFegin;
    @Autowired
    @Lazy
    private LoginFegin loginFegin;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
        StringBuffer requestURL = httpServletRequest.getRequestURL();
        log.info("前置拦截器1 preHandle： 请求的uri为：" + requestURL.toString());
        try {
            String ip = IpUtil.getIpAddr(httpServletRequest);
            String token = httpServletRequest.getHeader("token");
            String compamyKey=httpServletRequest.getHeader("companyKey");
            StringBuffer stringBuffer=new StringBuffer(ip).append(requestURL).append(JSON.toJSONString(httpServletRequest.getParameterMap()));
            if (redisUtil.requestLock(stringBuffer.toString())) {
                throw new FrequentlyException();
            }
            TokenRequest request = new TokenRequest();
            request.setIp(ip);
            request.setToken(token);
            if (o instanceof HandlerMethod) {
                HandlerMethod h = (HandlerMethod) o;
                ApiController apiController = h.getMethodAnnotation(ApiController.class);
                if (apiController != null) {
                    //验证是否需要进行登陆校验
                    if (apiController.isLogin()) {
                        if (StringUtils.isEmpty(token)) {
                            //未获取到token抛出异常
                            throw new LoginException();
                        }

                        ResultModel<TokenEntity> result = loginFegin.getLoginInfo(token);
                        if (result == null || result.getData() == null) {
                            throw new LoginException();
                        }
                        TokenEntity tokenEntity=result.getData();
                        log.info("登录验证获取的缓存信息：{}", JSON.toJSONString(tokenEntity));
                        if(null==tokenEntity){
                            throw new LoginException();
                        }

                        if(!tokenEntity.getCompanyKey().equals(compamyKey)){
                            log.info("companyKey不同：{}--{}",tokenEntity.getCompanyKey(),compamyKey);
                            throw new ParamException("登陆companyKey不同");
                        }
                        if (apiController.card()) {
                            if (null == tokenEntity.getMyCardId() ) {
                                throw new CardException();
                            }
                            if(tokenEntity.getMyCardId() <=0){
                                throw new CardException();
                            }
                            ResultModel resultModel=crmFegin.verifyExpired(new BusinessCardRequest() {{
                                setCardId(tokenEntity.getMyCardId());
                            }});
                            log.info("名片服务验证：{}",JSON.toJSONString(resultModel));
                            if(!resultModel.isSuccess()){
                                throw new CardNumServiceException();
                            }

                        }
                        if (apiController.company()) {
                            if (null == tokenEntity.getCId() ) {
                                throw new CompanyException();
                            }
                            if(tokenEntity.getCId() <= 0){
                                throw new CompanyException();
                            }
                        }
                        if (apiController.isBoss()) {
                            if (null == tokenEntity.getRoleId()) {
                                throw new BossException();
                            }
                            if(tokenEntity.getRoleId() <= 0){
                                throw new BossException();
                            }
                        }
                        BeanUtils.copyProperties(tokenEntity, request);
                        if(apiController.isParam()){
                            Object object=httpServletRequest.getAttribute("request");
                            String attribute = null;
                            JSONObject data;
                            if(null!=object){
                                attribute= JSON.toJSONString(object);
                            }
                            if(StringUtils.isEmpty(attribute)){
                                data=new JSONObject();
                            }else{
                                data=JSONObject.parseObject(attribute);
                            }
                            if(null==data){
                                data=new JSONObject();
                            }
                            data.put("token",token);
                            data.put("id",request.getId());
                            data.put("ip",request.getIp());
                            data.put("cId",request.getCId());
                            data.put("roleId",request.getRoleId());
                            data.put("myCardId",request.getMyCardId());
                            data.put("loginProgramName",request.getLoginProgramName());
                            data.put("logintime",request.getLogintime());
                            data.put("companyKey",request.getCompanyKey());
                            httpServletRequest.setAttribute("request", data.toJavaObject(apiController.paramClass()));
                        }
                    }


                }
            }
            httpServletRequest.setAttribute("tokenRequest", request);
            return true;
        } catch (FrequentlyException fe) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.FREQUENTLY);
            return false;
        } catch (LoginException l) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_LOGIN);
            return false;
        } catch (CompanyException ce) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_COMPANY);
            return false;
        } catch (CardException cee) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_ROLE);
            return false;
        }catch (CardNumServiceException cnse){
            ResultModel.returnJson(httpServletResponse, ResultEnum.CARD_OVERDUE);
            return false;
        }catch (BossException be) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_BOSS);
            return false;
        }catch (ParamException pe){
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_TOURIST);
            return false;
        }catch (Exception e) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.ERROR);
            return false;
        }
    }
}
